<?php


namespace App\Http\Controllers\Auth;


use App\Models\User\Patient;
use Illuminate\Http\Request;
use Validator;

class JwtController
{
    /**
     * @group 用户短信登录或注册
     *
     * 前端逻辑
     * 1. 首先调用auth/message/code获取短信验证码
     * 2. 调用该接口注册或登录
     * 3. 注册成功或登录成功都会返回一串token
     * 4. 把这一串token加在http headers中 key是Authorization value是返回的这一串token
     *
     * 1. 返回res说明 info是用户信息dict格式 token是会话 把这一串token加在http headers中 key是Authorization value是返回的这一串token
     * 2. name->姓名
     * 3. id->用户id号
     * 4. phone->用户手机号
     * 5. card->用户身份证号
     * 6. address->用户地址管理 json格式
     * 7. hospital_id->住院号
     * 8. register_id->登记号
     * 9. avatar->头像url信息 json格式
     * 10. bonus->餐券json格式
     *     fee->('优惠金额');
     *     type->1:A 2:B 3:C三种类型
     * 11. collection->收藏json格式
     *
     * 后端逻辑
     * 1. 查看用户是否已经激活 判断类型 未激活是注册逻辑 激活是登录逻辑
     * 2. 查看验证码是否过期
     * 3. 对比验证码是否正确
     * 4. 如果是注册添加一个新用户
     * 5. 发送token给前端页面
     *
     *
     * 返回状态码对应消息
     *
     * 400 参数错误
     * 411 至少需要提交密码或者短信验证码中的一个来验证
     * 412 用户还没有注册成功 要先执行获取短信验证码
     * 413 验证码已经失效了 需要重新发送
     * 414 验证码验证失败
     *
     * 200 注册成功 并且返回的内容是token 可以直接进行会话
     *
     * @bodyParam phone int required 手机号
     * @bodyParam code int required 验证码
     */
    function userLoginOrRegister(Request $request)
    {
        $type = 1;//默认是登录类型1 在后面会判断如果不存在则是注册类型2
        //数据验证
//        $validator = Validator::make($request->all(), genValidate());
//        if ($validator->fails()) {
//            return response()->json($validator->errors()->messages(), 400);
//        }

        //用户验证
        $phone = $request->get('phone');
        if (!self::validateUser($phone)) {
            $type = 2;
            //return response()->json('请先注册用户再登录',412);
        }

        $user = Patient::with(['addresses','avatar','bonus','collection'])->where('phone', '=', $phone)->first();
        if ($user === null) {
            return response()->json('请先注册用户再登录', 412);
        }

        $code = '';
        //根据类型来获取不同的时间
        if ($type === 1) {
            $time = $user->login_code_time;
            $code = (string) $user->login_code;
            $user->login_code = '';
        } elseif ($type === 2) {
            $time = $user->register_code_time;
            $code = (string)$user->register_code;
            $user->register_code = '';
        }
        //查看验证码是否过期
        if (!self::validateCodeTime($time)) {
            return response()->json('验证码已经失效 请重新发送', 413);
        };
        if (!($code === (string)$request->input('code', 'xxxx'))) {
            return response()->json('验证码错误', 414);
        }
        if($type === 2)
        {
            $user->is_register = true;
        }
        $user->save();

        $userId = $user->id;
        $userName = $user->name;
        $userPhone = $user->phone;
        $address=$user->addresses;
        $userInfo = array(
            'name'=>$userName,//姓名
            'id' =>$userId,
            'phone'=>$userPhone,//手机号
            'card'=>$user->card,//身份证
            'address'=>$address,//地址管理
            'hospital_id'=>$user->hospital_id,//住院号
            'register_id'=>$user->register_id,//登记号
            'avatar'=>$user->image,//头像
            'bonus'=>$user->bonus,//餐券
            'collection'=>$user->collection,//收藏
            'user_type'=>1,
        );

        $res = array(
            'info'=>$userInfo,
            'token'=>JwtToken::genUserToken($user),
        );
        return response()->json($res, 200);
    }

    /**
     * @group 用户注册->收到短信验证码后激活账户
     *
     *1. 查看这个用户是不是已经被注册了 已经被注册了就能被注册
     *2. 查看验证码的时间有效性 过期提示重新发送验证码
     *3. 对比验证码 激活用户
     *
     *
     * 返回状态码对应消息
     *
     * 400 参数错误
     * 411 用户已经被注册了 无法再次注册
     * 412 用户还有点发送验证码 就乱提交验证码
     * 413 验证码已经失效了 需要重新发送
     * 414 验证码验证失败
     *
     * 200 注册成功 并且返回的内容是token 可以直接进行会话
     *
     * @bodyParam phone int required 手机号
     * @bodyParam code int required 验证码
     */
    function userRegister(Request $request)
    {
        //数据验证
        $validator = Validator::make($request->all(), genValidate());
        if ($validator->fails()) {
            return response()->json($validator->errors()->messages(), 400);
        }

        $phone = $request->get('phone');
        $userCode = $request->get('code');
        if (self::validateUser($phone)) {
            return response()->json('该用户已经被注册了', 411);
        }
        $isExists = Patient::where('phone', '=', $phone)->exists();
        //如果存在说明用户还没有发送过验证码
        if (!$isExists) {
            return response()->json('请先发送验证码', 412);
        }
        $user = Patient::where('phone', '=', $phone)->first();
        $time = $user->register_code_time;
        //查看验证码是否过期
        if (!self::validateCodeTime($time)) {
            return response()->json('验证码已经失效 请重新发送', 413);
        };
        $code = $user->register_code;
        if ((string)$code != (string)$userCode) {
            return response()->json('验证码错误', 414);
        }
        $user->is_register = true;
        $user->save();
        return response()->json(JwtToken::genUserToken($user), 200);
    }

    //验证验证码是否过期 true未过期 false 过期了
    static private function validateCodeTime($time)
    {
        $res = strtotime($time) + JwtToken::getCodeExpireTime() - time();
        if ($res > 0) {
            return $res;
        }
        //return false;
        return true;
    }

    //判断用户是否已经注册成功了
    static private function validateUser($phone)
    {
        return Patient::where('phone', '=', $phone)->where('is_register', '=', true)->exists();
    }

    /**
     * @group 用户短信验证码->注册账户或登录前发送短信验证码接口
     *
     * 后端逻辑
     *1. 首先查看用户手机号是否存在 不存在就生成一个新用户
     *2. 如果这个用户已经激活就不发送激活验证码了 转到步骤5
     *3. 首先查看用户验证码是否在最近发送过 如果发送时间间隔小于设定的值 则提示用户等会再试
     *4. 发送验证码 插入数据库 记录验证码发送时间
     *5. 这一步说明用户是想获取登录验证码 首先验证码登录验证码是否发送期有效 提示还需要过xx秒才能发送验证码
     *6. 最后一次发送时间无效则发送登录验证码
     *
     * 返回状态码对应消息
     *
     * 400 参数错误
     * 411 用户已经被注册了不能发送验证码
     * 412 验证码要在xx间隔之后才能再重新发送
     * 200 验证码发送成功 请用户查收
     *
     * @bodyParam phone int required 手机号
     */
    function MsgCode(Request $request)
    {
        //数据验证
//        $validator = Validator::make($request->all(), genValidate());
//        if ($validator->fails()) {
//            return response()->json($validator->errors()->messages(), 400);
//        }
        $phone = $request->get('phone');
        $code = self::genCode();
        $now = date("Y-m-d H:i:s");
        //判断用户是否已经被注册了
        if (self::validateUser($phone)) {
            $user = Patient::where('phone', '=', $phone)->first();
            $time = $user->login_code_time;
            //判断验证码是否已经过期了 过期了就可以重新发送
//            if (self::validateCodeTime($time)) {
//                $dTime = self::validateCodeTime($time);
//                return response()->json("验证码已经发送了 请于{$dTime}秒之后再试", 412);
//            } else {
                $user->login_code_time = $now;
                $user->login_code = $code;
                $user->save();
                return response()->json("验证码发送成功");
//            }
        }
        $isExists = Patient::where('phone', '=', $phone)->exists();
        if ($isExists) {
            $user = Patient::where('phone', '=', $phone)->first();
            $time = $user->register_code_time;
            //判断验证码是否已经过期了 过期了就可以重新发送
            if (self::validateCodeTime($time)) {
                $dTime = self::validateCodeTime($time);
                return response()->json("验证码已经发送了 请于{$dTime}秒之后再试", 412);
            } else {
                $user->register_code_time = $now;
                $user->register_code = $code;
                $user->save();
                return response()->json("验证码发送成功");
            }
        } else {
            $user = Patient::create(
                ["phone" => $phone, 'name' => uniqid()]
            );
            $user->register_code = $code;
            $user->register_code_time = $now;
        }
        $user->save();
        return response()->json('验证码发送成功');
    }

    //生成一串验证码
    static function genCode(int $len = 6, bool $isNumber = true)
    {
        $code = "";
        if ($isNumber) {
            for ($i = 0; $i < $len; $i++) {
                $code .= (string)random_int(1, 9);
            }
        }
        return '123456';
        return $code;
    }
    //TODO 商户登录逻辑 后台登录逻辑

}